package com.siki.www.clock.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.siki.salessystemcommon.entity.ClockInfo;
import com.siki.salessystemcommon.entity.ClockLog;
import com.siki.salessystemcommon.entity.enumeration.PeopleType;
import com.siki.salessystemcommon.entity.enumeration.PhysicalCondition;
import com.siki.salessystemcommon.entity.enumeration.TemperatureStatus;
import com.siki.salessystemcommon.mapper.ClockInfoMapper;
import com.siki.salessystemcommon.mapper.ClockLogMapper;
import com.siki.www.clock.dto.SubmitClockInfoDTO;
import com.siki.www.clock.service.ClockService;
import com.siki.www.clock.vo.ClockInfoByDateVO;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;
import java.util.Optional;
import java.util.regex.Pattern;

/**
 * @author Siki in 2021/6/19
 */
@Service
public class ClockServiceImpl implements ClockService {
    private final ClockInfoMapper clockInfoMapper;
    private final ClockLogMapper clockLogMapper;

    public ClockServiceImpl(ClockInfoMapper clockInfoMapper, ClockLogMapper clockLogMapper) {
        this.clockInfoMapper = clockInfoMapper;
        this.clockLogMapper = clockLogMapper;
    }


    @Override
    public void insertClockInfo(SubmitClockInfoDTO dto) {
        // 插入clock表的逻辑
        String now = LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
        QueryWrapper<ClockInfo> wrapper =
                // 查询当前用户当天有没有打卡
                new QueryWrapper<ClockInfo>().eq("cas_id", dto.getCasId());
        ClockInfo info = getClockInfoByStudentId(wrapper);
        Long days = 1L;
        // 情况1,新用户,没有打卡记录,则插入新数据
        if (info == null) {
            info = new ClockInfo();
            BeanUtil.copyProperties(dto, info);
            info.setClockDays(days);
            clockInfoMapper.insert(info);
            // 情况2, 已有打卡记录, 但日期与今日不符合
        } else if (!now.equals(info.getClockDate()
                .format(DateTimeFormatter.ISO_LOCAL_DATE))) {
            days = info.getClockDays();
            // 如果本次打卡和上次相差超过一天，连续打卡中断
            if (ChronoUnit.DAYS.between(info.getClockDate(), LocalDate.now()) > 1) {
                days = null;
            }
            BeanUtil.copyProperties(dto, info);
            days = days == null ? 1 : days + 1;
            info.setClockDays(days);
            info.setUpdateTime(LocalDateTime.now());
            clockInfoMapper.updateById(info);
        }

        // 插入log表逻辑
        // 按当天日期和学号查询
        QueryWrapper<ClockLog> eq = new QueryWrapper<ClockLog>().eq("cas_id", dto.getCasId())
                .eq("clock_date", now);
        ClockLog logInfo = clockLogMapper.selectOne(eq);
        // 不等于空说明有记录,则直接结束
        if (logInfo != null) {
            return;
        }
        ClockLog log = new ClockLog();
        BeanUtil.copyProperties(dto, log);
        // 只要一个不是正常, 打卡状态就不正常
        log.setAlertStatus((byte) (!PeopleType.NormalPerson.equals(PeopleType.valueOf(dto.getPeopleType())) ||
                !TemperatureStatus.NORMAL.equals(TemperatureStatus.valueOf(dto.getTemperatureStatus())) ||
                !PhysicalCondition.WELL.equals(PhysicalCondition.valueOf(dto.getPhysicalCondition())) ? 1 : 0));
        log.setClockDays(days);
        clockLogMapper.insert(log);
    }

    /**
     * 查询当日打卡信息
     *
     * @param token 学号
     * @return
     */
    @Override
    public ClockInfoByDateVO getSubmitInfoByDate(String token) {
        String now = LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
        QueryWrapper<ClockInfo> qw = new QueryWrapper<ClockInfo>()
                .eq("clock_date", now)
                .eq("cas_id", token);
        // 查询当日打卡信息, 若未打卡则为空
        return new ClockInfoByDateVO(getClockInfoByStudentId(qw));
    }

    @Override
    public ClockInfoByDateVO getRecord(String token) {
        return new ClockInfoByDateVO(getClockInfoByStudentId(new QueryWrapper<ClockInfo>()
                .eq("cas_id", token)));
    }


    /**
     * 根据学号查询打卡信息
     *
     * @return
     */
    private ClockInfo getClockInfoByStudentId(QueryWrapper<ClockInfo> qw) {
        if (qw == null) {
            qw = new QueryWrapper<ClockInfo>();
        }
        return Optional.ofNullable(clockInfoMapper
                .selectOne(qw)).orElse(null);
    }

    /**
     * 查询单个打卡日志
     *
     * @param qw
     * @return
     */
    private ClockInfo getClockLogByStudentId(QueryWrapper<ClockInfo> qw) {
        if (qw == null) {
            qw = new QueryWrapper<ClockInfo>();
        }
        return Optional.ofNullable(clockInfoMapper
                .selectOne(qw)).orElse(null);
    }

}
